/*
 * PrimitiveRenderer.h
 *
 *  Created on: 2011/10/23
 *      Author: naoki
 */

#ifndef INCLUDED_NTENGINE_SCENE_PRIMITIVERENDERER_H
#define INCLUDED_NTENGINE_SCENE_PRIMITIVERENDERER_H

#include "NTEngine/Graphics/Enum.h"

namespace NTEngine {

namespace Graphics {
class Texture;
} // namespace Graphisc

namespace Math {
class Matrix4x4;
class Vector4;
class Vector3;
class Vector2;
} // namespace Math

namespace Scene {

/**
 * @brief 直接三角形、線分、点、2D長方形を描画するための便利クラス。
 * 速度的にはかなり無駄が多い。
 */
class PrimitiveRenderer {
public:
	/**
	 * 頂点数と、その他命令の数を指定して構築
	 *
	 * @param vertexCapacity
	 * @param commandCapacity
	 */
	static PrimitiveRenderer create( int vertexCapacity, int commandCapacity );

	/**
	 * @brief
	 */
	void setTexture( Graphics::Texture );

	/**
	 * @brief
	 */
	void enableDepthTest( bool );

	/**
	 * @brief
	 */
	void enableDepthWrite( bool );

	/**
	 * @brief
	 */
	void setBlendMode( Graphics::BlendMode );

	/**
	 * @brief
	 */
	void setCullMode( Graphics::CullMode );

	/**
	 * @brief
	 */
	void setTransform( const Math::Matrix4x4& );

	/**
	 * @brief 三角形を変換済み頂点で書く。つまりpは4要素ベクタ。
	 */
	void addTransformedTriangle(
		const Math::Vector4& pos0,
		const Math::Vector4& pos1,
		const Math::Vector4& pos2,
		const Math::Vector2& uv0,
		const Math::Vector2& uv1,
		const Math::Vector2& uv2,
		unsigned color0 = 0xffffffff,
		unsigned color1 = 0xffffffff,
		unsigned color2 = 0xffffffff);

	/**
	 * @brief 三角形を変換済み頂点で書く。テクスチャなし。
	 */
	void addTransformedTriangle(
		const Math::Vector4& pos0,
		const Math::Vector4& pos1,
		const Math::Vector4& pos2,
		unsigned color0 = 0xffffffff,
		unsigned color1 = 0xffffffff,
		unsigned color2 = 0xffffffff);

	/**
	 * @brief 三角形を描く
	 */
	void addTriangle(
		const Math::Vector3& pos0,
		const Math::Vector3& pos1,
		const Math::Vector3& pos2,
		const Math::Vector2& uv0,
		const Math::Vector2& uv1,
		const Math::Vector2& uv2,
		unsigned color0 = 0xffffffff,
		unsigned color1 = 0xffffffff,
		unsigned color2 = 0xffffffff );

	/**
	 * @brief 三角形を描く。テクスチャなし
	 */
	void addTriangle(
		const Math::Vector3& pos0,
		const Math::Vector3& pos1,
		const Math::Vector3& pos2,
		unsigned color0 = 0xffffffff,
		unsigned color1 = 0xffffffff,
		unsigned color2 = 0xffffffff );

	/**
	 * @brief 線分を描く。
	 */
	void addLine(
		const Math::Vector3& pos0,
		const Math::Vector3& pos1,
		const Math::Vector2& uv0,
		const Math::Vector2& uv1,
		unsigned color0 = 0xffffffff,
		unsigned color1 = 0xffffffff );

	/**
	 * @brief 線分を描く。テクスチャなし。
	 */
	void addLine(
		const Math::Vector3& pos0,
		const Math::Vector3& pos1,
		unsigned color0 = 0xffffffff,
		unsigned color1 = 0xffffffff );

	/**
	 * @brief 点を描く。
	 */
	void addPoint(
		const Math::Vector3& pos,
		const Math::Vector2& uv,
		unsigned color = 0xffffffff );

	/**
	 * @brief 点を描く。テクスチャなし
	 */
	void addPoint(
		const Math::Vector3& pos,
		unsigned color = 0xffffffff );

	/**
	 * @brief Z=0平面に長方形を描く。座標系はスクリーン座標。
	 */
	void addRectangle(
		const Math::Vector2& pos0,
		const Math::Vector2& pos1,
		const Math::Vector2& uv0,
		const Math::Vector2& uv1,
		unsigned color = 0xffffffff,
		float depth = 0.f );

	/**
	 * @brief Z=0平面に長方形を描く。座標系はスクリーン座標。テクスチャなし。
	 */
	void addRectangle(
		const Math::Vector2& pos0,
		const Math::Vector2& pos1,
		unsigned color = 0xffffffff,
		float depth = 0.f );

	/**
	 * @brief 描画
	 */
	void draw();

	PrimitiveRenderer();
	PrimitiveRenderer( const PrimitiveRenderer& );
	~PrimitiveRenderer();
	operator void*() const;
	PrimitiveRenderer& operator=( const PrimitiveRenderer& );
	void release();
	bool operator==( const PrimitiveRenderer& ) const;
	bool operator!=( const PrimitiveRenderer& ) const;
	int referenceCount() const;
private:
	class Impl;
	Impl* mImpl;
};
} // namespace Scene
} // namespace NTEngine

#endif // INCLUDED_NTENGINE_SCENE_PRIMITIVERENDERER_H
